home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / gres.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  3KB  |  177 lines

  1. /* gres - grep and substitute        Author: Martin C. Atkins */
  2.  
  3. /*
  4.  *    globally search, and replace
  5.  *
  6.  *<-xtx-*>cc -o gres gres.c -lregexp
  7.  */
  8.  
  9. /*
  10.  *    This program was written by:
  11.  *        Martin C. Atkins,
  12.  *        University of York,
  13.  *        Heslington,
  14.  *        York. Y01 5DD
  15.  *        England
  16.  *    and is released into the public domain, on the condition
  17.  *    that this comment is always included without alteration.
  18.  */
  19.  
  20. #include <regexp.h>
  21. #include <string.h>
  22. #include <stdio.h>
  23.  
  24. #define MAXLINE (1024)
  25.  
  26. int status = 1;
  27. char *usagemsg = "Usage: gres [-g] search replace [file ...]\n";
  28. char *progname;
  29. int gflag = 0;            /* != 0 => only do first substitution on line */
  30.  
  31. main(argc, argv)
  32. int argc;
  33. char *argv[];
  34. {
  35.   regexp *exp;
  36.   char *repstr;
  37.   char **argp = &argv[1];
  38.  
  39.   progname = argv[0];
  40.   if (*argp != 0 && argp[0][0] == '-' && argp[0][1] == 'g') {
  41.     gflag = 1;
  42.     argp++, argc--;
  43.   }
  44.   if (argc < 3) {
  45.     std_err(usagemsg);
  46.     exit(2);
  47.   }
  48.   if (argp[0][0] == '\0') {
  49.     std_err("gres: null match string is silly\n");
  50.     exit(2);
  51.   }
  52.   if ((exp = regcomp(*argp++)) == (regexp *) NULL) {
  53.     std_err("gres: regcomp failed\n");
  54.     exit(2);
  55.   }
  56.   repstr = *argp++;
  57.   if (*argp == 0)
  58.     process(stdin, exp, repstr);
  59.   else
  60.     while (*argp) {
  61.         FILE *inf;
  62.  
  63.         if (strcmp(*argp, "-") == 0)
  64.             process(stdin, exp, repstr);
  65.         else {
  66.             if ((inf = fopen(*argp, "r")) == (FILE *) NULL) {
  67.                 std_err("gres: Can't open ");
  68.                 std_err(*argp);
  69.                 std_err("\n");
  70.                 status = 2;
  71.             } else {
  72.                 process(inf, exp, repstr);
  73.                 fclose(inf);
  74.             }
  75.         }
  76.         argp++;
  77.     }
  78.   exit(status);
  79. }
  80.  
  81. /* This routine does the processing. */
  82. process(inf, exp, repstr)
  83. FILE *inf;
  84. regexp *exp;
  85. char *repstr;
  86. {
  87.   char ibuf[MAXLINE];
  88.  
  89.   while (fgets(ibuf, MAXLINE, inf) != (char *) NULL) {
  90.     char *cr = strchr(ibuf, '\n');
  91.     if (cr == 0)
  92.         std_err("gres: Line broken\n");
  93.     else
  94.         *cr = '\0';
  95.     if (regexec(exp, ibuf, 1)) {
  96.         pline(exp, ibuf, repstr);
  97.         if (status != 2) status = 0;
  98.     } else
  99.         puts(ibuf);
  100.   }
  101. }
  102.  
  103. void regerror(s)
  104. char *s;
  105. {
  106.   std_err("gres: ");
  107.   std_err(s);
  108.   std_err("\n");
  109.   exit(2);
  110. }
  111.  
  112. char *getbuf(exp, repstr)
  113. regexp *exp;
  114. char *repstr;
  115. {
  116.   char *malloc();
  117.   void free();
  118.   static bufsize = 0;
  119.   static char *buf = 0;
  120.   int guess = 10;
  121.   int ch;
  122.  
  123.   while (*repstr) {
  124.     switch (*repstr) {
  125.         case '&':
  126.         guess += exp->endp[0] - exp->startp[0];
  127.         break;
  128.         case '\\':
  129.         if ((ch = *++repstr) < '0' || ch > '9')
  130.             guess += 2;
  131.         else {
  132.             ch -= '0';
  133.             guess += exp->endp[ch] - exp->startp[ch];
  134.         }
  135.         break;
  136.         default:    guess++;
  137.     }
  138.     repstr++;
  139.   }
  140.   if (bufsize < guess) {
  141.     if (buf != 0) free((char *) buf);
  142.     buf = malloc(guess);
  143.   }
  144.   return buf;
  145. }
  146.  
  147. pline(exp, ibuf, repstr)
  148. regexp *exp;
  149. char ibuf[];
  150. char *repstr;
  151. {
  152.   do {
  153.     dosub(exp, ibuf, repstr);
  154.     ibuf = exp->endp[0];
  155.     if (*ibuf == '\0') break;
  156.     if (ibuf == exp->startp[0]) putchar(*ibuf++);
  157.   } while (!gflag && regexec(exp, ibuf, 0));
  158.   puts(ibuf);
  159. }
  160.  
  161. /* Print one subsitution. */
  162. dosub(exp, ibuf, repstr)
  163. regexp *exp;
  164. char ibuf[];
  165. char *repstr;
  166. {
  167.   char *buf = getbuf(exp, repstr);
  168.   char *end = exp->startp[0];
  169.   int ch = *end;
  170.  
  171.   *end = '\0';
  172.   fputs(ibuf, stdout);        /* output the initial part of line */
  173.   *end = ch;
  174.   regsub(exp, repstr, buf);
  175.   fputs(buf, stdout);
  176. }
  177.